#include <cstdio>
#include <list>
#include <iostream>


#include <unistd.h>

//users' include files
#include "data_process.h"
#include "game_config.h"

extern GameStat g_gamestat;
extern std::list<Snake> snake_list;

//extern PicCode map[80][80];
extern Map global_map;

/**
 * @brief 蛇行走线程
 * @points: 
 1. 更新每个蛇节点的坐标。
 1-1  每一个节拍变一次：（蛇头除外）后面蛇节点的坐标==前面蛇节点的坐标（蛇头的坐标另外计算）
 （这里利用链表这种数据结构，蛇头插入（每个节拍都要插，相当于队列尾），尾删除（没吃到食物就删除，相当于队列头）
 
 1-2  当吃到食物之后：在蛇的尾巴插入节点（插入的值==上一节拍蛇尾的坐标）
 * @param arg 
 * @return void* 
 */
void* snake_move(void* arg)
{
    while(1)
    {
        #if 0
        if(g_gamestat != GAME_STARTED)
        {
            printf("game not started!\n");
            sleep(5);
            continue;
        }
        #endif
        for(Snake &temp_snake:snake_list)//注意！！此处必须加&，因为C++的foreach()中的第一变量是复制，而不是引用！！！
        {
            #if 1
            if(!temp_snake.isGameStarted())//如果蛇对应玩家并没有开始游戏，那么处理下一条蛇,不要让蛇移动
            {
                std::cout << "current snake game not started" <<std::endl;
                continue;
            }
            #endif
            temp_snake.snake_move();
        }
        //处理完所有蛇的数据之后，延时一段时间
        //sleep(1);
        sleep(GAME_TICK);
    }
}



void ClientData::parse_data(Snake &snake)
{
    //1. 先解析客户的命令
    /*
    typedef enum {
        START_GAME = 1,
        DATA_ERROR,
        EXIT_GAME,
    }GameCmd;
    */
   std::cout << "Client data received! cdata.cmd =" <<m_cmd << "\tcdata.dir=" <<m_dir<<std::endl; 
   
   switch(m_cmd)
   {
    case START_GAME:
    {
        std::cout << "player will start game!"<<std::endl;
        snake.set_user_stat(GAME_STARTED);
    }
    break;

    case EXIT_GAME:
    case DATA_ERROR:
    {
        snake.set_user_stat(GAME_EXITED);

        //1. 此时应该让当前的蛇，从list里面清除掉
        if(!snake_list.empty())
        {
            snake_list.remove(snake);
            snake.snake_die();

            //2. 让蛇身处的坐标，在地图上恢复为原样
            //这个需要遍历蛇身坐标，首先拿出整条蛇
            /*
            auto snake_body = snake.get_snake_total();
            for(auto siter=snake_body.begin(); siter!= snake_body.end(); siter++)
            {
                global_map.renew_to_mapcolor(siter->x, siter->y);
            }
            */
            std::cout << "A user log out! and tbe snake is remove from the list!" <<std::endl;
            bufferevent_free(snake.get_snake_evp());//销毁蛇的event,正常运行
            //snake.~Snake();//销毁蛇对象（此处可能出现问题，二次销毁？？？）
        }
        break;
    }
    
    default:
    {
        break;
    }
   }

    if(!snake.isGameStarted())//如果游戏未开始，则不解析方向相关的数据
    {
        return;
    }

   SnakeNode temp_head = snake.get_snake_head();

    //2. 再解析客户端的方向指令
    switch(m_dir)
    {
        case UP:
            if(temp_head.dir != DOWN)
            {
                snake.set_snake_head_dir(UP);
                printf("Snake Dir is set to UP\n");
            }
            break;
        case DOWN:
            if(temp_head.dir != UP)
            {
                snake.set_snake_head_dir(DOWN);
                printf("Snake Dir is set to DOWN\n");
            }
            break;
        case LEFT:
            if(temp_head.dir != RIGHT)
            {
                snake.set_snake_head_dir(LEFT);
                printf("Snake Dir is set to LEFT\n");
            }
            break;
        case RIGHT:
            if(temp_head.dir != LEFT)
            {
                snake.set_snake_head_dir(RIGHT);
                printf("Snake Dir is set to RIGHT\n");
            }
            break;
        default:
            break;
    }
    
}

/*
*@func:得到当前发送给客户端的地图的起点（包括x和y)
*@param:start_x, start_y 是传出参数, 另外需要蛇的头的起点的位置(h。 

*/
void get_client_map_origin(const int head_x, const int head_y, int *start_x, int *start_y)
{

    //判断head_x的位置
    #if 1
    if(head_x < 20)
    {
        *start_x = 0;
    }
    else if(head_x >= 60)
    {
        *start_x = 40;
    }
    else //（head_x [20, 60]之间
    {
        *start_x = head_x - 20;
    }
    #else
    if(head_x < 40)//head_x ->[0, 39]
    {
        *start_x = 0;
    }
    else if(head_x >= 40)//head_x -->[40, 79]
    {
        *start_x = 40;
    }
    #endif


    #if 1
    //判断head_y 的位置
    if(head_y < 20) //head->[0,19]共20个点
    {
        *start_y = 0;
    }
    else if(head_y >= 60) //head->[60, 79] 共20个点
    {
        *start_y = 40;
    }
    else //（head_x [20, 59)之间
    {
        *start_y = head_y - 20;
    }
    #else
    if(head_y < 40)//head_x ->[0, 39]
    {
        *start_y = 0;
    }
    else if(head_y >= 40)//head_x -->[40, 79]
    {
        *start_y = 40;
    }
    #endif

}
